﻿//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Licensed under the MIT License
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////
#include "GbmpModel.h"
#include "GbmpDefines.h"
#include "OwnerPtr.h"
#include "WeakPtr.h"
#include "ElementId.h"
#include "GbmpCalculatorBase.h"
#include "IElementShapeHandle.h"
#include "IElementViewSpecificShapeComponent.h"
#include "IElementShapeHandleBehavior.h"
#include "IElementUiManipulatorComponent.h"
#include "IElementTransformationComponent.h"
#include "IElementCopyPasteComponent.h"
#include "GbmpQuickCast.h"
#include "DbDataSchema.h"
#include "NdbObjectSchematic.h"
#include "IParameterOverride.h"
#include "IElementRegenerationComponent.h"
#include "IElementParametersCustomizer.h"
#include "ModelViewSymbolNewParameterOverrideBase.h"
#include "IElementCopyPasteComponent.h"

namespace gcmp
{
    class IElement;
    class IGraphicsElementShape;
    class IModelView;
    class IGraphicsElementShape;
    class IDocument;
    class IElementParentReporter;
    class IElementParametersCustomizer;
    enum class SectionViewSymbolNewAuxiliaryType;

    // 剖面标志夹点位置更新行为
    class GBMP_MODEL_EXPORT SectionViewSymbolNewGripPointBehavior :public NdbObjectSchematic, public IElementShapeHandleBehavior
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewGripPointBehavior, gcmp::NdbObjectSchematic, BE87E0D0 - DAB3 - 4C9F - A3F4 - 64FB33075292, gbmpmodel, gcmp::IElementShapeHandleBehavior)
            DATA(IDocument*, Document)
            DATA(ElementId, ModelViewId)    //表示这个夹点在哪个视图上显示的(切换视图夹点会刷新)
            DATA(ElementId, ElementShapeHandleId)
            DBOBJECT_DATA_END

    public:
        static OwnerPtr<IElementShapeHandleBehavior> Create(IDocument* pDoc, const ElementId& modelViewId);
        virtual ~SectionViewSymbolNewGripPointBehavior() {}

    public:
        virtual IDocument* GetDocument() const override { return GetDocument__(); }
        void SetDocument(const IDocument* pDoc) { SetDocument__(pDoc); }

        virtual ElementId GetModelViewId() const override { return GetModelViewId__(); }
        void SetModelViewId(const ElementId &modelViewId) { SetModelViewId__(modelViewId); }

        virtual ElementId GetElementShapeHandleId() const override { return GetElementShapeHandleId__(); }
        virtual void SetElementShapeHandleId(const ElementId& id) override { return SetElementShapeHandleId__(id); }

        virtual void GetCalculators(ICalculatorCollection* calculators) const override;
        virtual bool Translate(const IElementMoveContext & moveContext) override;

        virtual OwnerPtr<IGraphicsElementShape> CreateGrahicsElementShapeInModelView(const IModelView* pModelView) const override;
        virtual void ReportParents(IElementParentReporter& reporter) const override;

        virtual void UpdatePosition() override;
        virtual void UpdatePositionIndexInMasterElement() override {};

        virtual void GetNearestPoint(Vector3d& nearPoint) const override;

        virtual bool FinishEditing() override { return false; }
        virtual bool GetHandleCommandString(const IObject* commandEnvironment, std::wstring& commandStr, CommandParameters& cmdParams) const override;

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        SectionViewSymbolNewGripPointBehavior(IDocument* pDoc, const ElementId& modelViewId);
        IElementShapeHandle* GetElementShapeHandle() const;
        IElement * GetMasterElement() const;
    };
    
    // 剖面标志辅助线位置更新行为
    class GBMP_MODEL_EXPORT SectionViewSymbolNewBorderBehavior :public NdbObjectSchematic, public IElementShapeHandleBehavior
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewBorderBehavior, gcmp::NdbObjectSchematic, D0E5B020 - BCC0 - 43CA - AAF3 - 2E3CC7A947A3, gbmpmodel, gcmp::IElementShapeHandleBehavior)
            DATA(IDocument*, Document)
            DATA(ElementId, ModelViewId)    //表示这个夹点在哪个视图上显示的(切换视图夹点会刷新)
            DATA(ElementId, ElementShapeHandleId)
            DBOBJECT_DATA_END

    public:
        static OwnerPtr<IElementShapeHandleBehavior> Create(IDocument* pDoc, const ElementId& modelViewId);
        virtual ~SectionViewSymbolNewBorderBehavior() {}

    public:
        virtual IDocument* GetDocument() const override { return GetDocument__(); }
        void SetDocument(const IDocument* pDoc) { SetDocument__(pDoc); }

        virtual ElementId GetModelViewId() const override { return GetModelViewId__(); }
        void SetModelViewId(const ElementId &modelViewId) { SetModelViewId__(modelViewId); }

        virtual ElementId GetElementShapeHandleId() const override { return GetElementShapeHandleId__(); }
        virtual void SetElementShapeHandleId(const ElementId& id) override { return SetElementShapeHandleId__(id); }

        virtual void GetCalculators(ICalculatorCollection* calculators) const override;
        virtual bool Translate(const IElementMoveContext & moveContext) override;

        virtual OwnerPtr<IGraphicsElementShape> CreateGrahicsElementShapeInModelView(const IModelView* pModelView) const override;
        virtual void ReportParents(IElementParentReporter& reporter) const override;

        virtual void UpdatePosition() override;
        virtual void UpdatePositionIndexInMasterElement() override {};

        virtual void GetNearestPoint(Vector3d& nearPoint) const override;

        virtual bool FinishEditing() override { return false; }
        virtual bool GetHandleCommandString(const IObject* commandEnvironment, std::wstring& commandStr, CommandParameters& cmdParams) const override;

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        SectionViewSymbolNewBorderBehavior(IDocument* pDoc, const ElementId& modelViewId);
        IElementShapeHandle* GetElementShapeHandle() const;
        IElement * GetMasterElement() const;
    };
    

    // 剖面标志视图相关行为
    class SectionViewSymbolNewViewSpecificShapeComponent : public NdbObjectSchematic,
        public IElementViewSpecificShapeComponent
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewViewSpecificShapeComponent, gcmp::NdbObjectSchematic, EDE84A94 - A1DD - 4044 - BCFC - E2CB741E93E2, gbmpmodel, IElementViewSpecificShapeComponent)
            DATA(OwnerPtr<IRenderPriorityOffsetProvider>, RenderPriorityOffsetProvider)
            DATA_TRANSIENT(IElement*, pOwnerElement)
            DATA(OwnerPtr<IGraphicsNodeVisibilityCustomizer>, GraphicsNodeVisibilityCustomizer)
        DBOBJECT_DATA_END
    public:
        virtual ~SectionViewSymbolNewViewSpecificShapeComponent() {}

        virtual bool SetOwnerElement(IElement* pOwnerElement) override;
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement; }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement; }
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    public:
        virtual bool IsVisibleInModelView(const IModelView* pModelView) const override;
        virtual OwnerPtr<IGraphicsElementShape> CreateViewSpecificElementShape(const IModelView* pModelView) const override;
        virtual bool IsCuttableByModelViewRange(const IModelView* pModelView) const override { return false; }
        virtual void ReportDependentElements(std::vector<ElementId>& dependentElementIds) const override;
    
        virtual void SetRenderPriorityOffsetProvider(OwnerPtr<IRenderPriorityOffsetProvider> opProvider) override;
        virtual const IRenderPriorityOffsetProvider* GetRenderPriorityOffsetProvider() const override;
        virtual IRenderPriorityOffsetProvider* GetRenderPriorityOffsetProvider() override;

        virtual void SetGraphicsNodeVisibilityCustomizer(OwnerPtr<IGraphicsNodeVisibilityCustomizer> opCustomizer) override;
        virtual const IGraphicsNodeVisibilityCustomizer* GetGraphicsNodeVisibilityCustomizer() const override;
        virtual IGraphicsNodeVisibilityCustomizer* GetGraphicsNodeVisibilityCustomizer() override;
    };

    // 剖面标志UI操纵器组件
    class SectionViewSymbolNewUiManipulatorComponent : public NdbObjectSchematic, public IElementUiManipulatorComponent
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewUiManipulatorComponent, gcmp::NdbObjectSchematic, EEFF9CE4 - B253 - 4891 - BE4D - 460192CC4610, gbmpmodel, IElementUiManipulatorComponent)
        DBOBJECT_DATA_END
    public:
        virtual bool SetOwnerElement(IElement* pOwnerElement) override { m_pOwnerElement = pOwnerElement; return true; }
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement; }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement; }
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        ElementId CreateGripPoint(SectionViewSymbolNewAuxiliaryType type, const gcmp::ElementId& modelviewId) const;
        ElementId CreateBorder(SectionViewSymbolNewAuxiliaryType type, const gcmp::ElementId& modelviewId) const;

    private:
        IElement* m_pOwnerElement;
    };

    // 剖面标志移动、旋转行为
    class SectionViewSymbolNewTransformationComponent :public NdbObjectSchematic, public IElementTransformationComponent
    {
        DBOBJECT_DATA_BEGIN(gcmp, SectionViewSymbolNewTransformationComponent, gcmp::NdbObjectSchematic, D360AF8D - 560C - 4E02 - A5E9 - 92F7C1AB22E6, gbmpmodel)
        DBOBJECT_DATA_END
    public:
        virtual bool SetOwnerElement(IElement* pOwnerElement) override { m_pOwnerElement = pOwnerElement; return true; }
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement; }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement; }

        virtual bool CanBeMoved(std::wstring* explanation = nullptr) const override;
        virtual bool Translate(const IElementMoveContext& moveContext) override;

        virtual bool CanBeRotated(std::wstring* explanation = nullptr) const override;
        virtual bool Rotate(const Vector3d& pointOnVec, const Vector3d& rotateDir, double rotateAngle) override;

        virtual bool CanBeScaled(std::wstring* explanation = nullptr) const override { return false; }
        virtual bool Scale(const Vector3d& basePt, float scaleFactor) override { return false; }

        virtual bool Transform(const Matrix4d& matrix) override;
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        IElement* m_pOwnerElement;
    };

    // 剖面标志参数行为
    class SectionViewSymbolNewParametersCustomizer : public NdbObjectSchematic, public IElementParametersCustomizer
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewParametersCustomizer, gcmp::NdbObjectSchematic, 2AEEAD77-DADA-4AF1-9227-4A7F86FA6E02, gbmpmodel, IElementParametersCustomizer)
        DBOBJECT_DATA_END
    public:
        SectionViewSymbolNewParametersCustomizer(const IElement* pElement) :m_pOwnerElement(pElement) {};

        virtual OwnerPtr<IParameter> GetNativeParameter(int paramDefId) const override;
        virtual bool SetNativeParameter(const IParameter *param, std::wstring* errorMsg) override;
        virtual void ReportParameterDefinitions(std::vector<int>* pParamDefIds) const override;
        virtual bool IsParameterModifiable(int parameterId) const override;
        virtual bool IsPresetParameter(const UniIdentity& paramDefUid) const override { return true; }
        virtual void FilterParameterValues(const UniIdentity& paramDefUid, 
            std::vector<OwnerPtr<IParameterValueStorage>>& values) const override {}

    public:
        virtual bool SetOwnerElement(IElement* pOwnerElement) override { m_pOwnerElement = pOwnerElement; return true; }
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement.Get(); }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement.Get(); }

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        const IElementParameters* GetSectionModelViewParameters() const;
        IElementParameters* GetSectionModelViewParameters();
    private:
        WeakPtr<IElement> m_pOwnerElement;
    };

    // 剖面视图标记名字参数定制
    class SectionViewSymbolNewNameParameterOverride : public NdbObjectSchematic, public ModelViewSymbolNewParameterOverrideBase
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewNameParameterOverride, gcmp::NdbObjectSchematic, 4895B382 - 05B7 - 46EE - AA8F - D785FEF77401, gbmpmodel, gcmp::IParameterOverride)
            DATA_TRANSIENT(IElement*, pOwnerElement)
            DBOBJECT_DATA_END

    public:
        SectionViewSymbolNewNameParameterOverride(IElement* pElement) :m_pOwnerElement(pElement) {};
        DECLARE_MODEL_VIEW_SYMBOL_NEW_PARAMETER_OVERRID_METHODS

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        virtual const UniIdentity& GetUidForParameterOverride() const override;
    };

    // 剖面视图标记顶部偏移参数定制
    class SectionViewSymbolNewTopPlaneOffsetParameterOverride : public NdbObjectSchematic, public ModelViewSymbolNewParameterOverrideBase
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewTopPlaneOffsetParameterOverride, gcmp::NdbObjectSchematic, 9E9399E6 - 5D23 - 438C - B1A6 - CD058AE1803E, gbmpmodel, gcmp::IParameterOverride)
            DATA_TRANSIENT(IElement*, pOwnerElement)
            DBOBJECT_DATA_END

    public:
        SectionViewSymbolNewTopPlaneOffsetParameterOverride(IElement* pElement) :m_pOwnerElement(pElement) {};
        DECLARE_MODEL_VIEW_SYMBOL_NEW_PARAMETER_OVERRID_METHODS

    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }

    private:
        virtual const UniIdentity& GetUidForParameterOverride() const override;
    };

    //Regeneration Behavior
    class SectionViewSymbolNewRegenerationBehavior : public NdbObjectSchematic, public IElementRegenerationComponent
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewRegenerationBehavior, gcmp::NdbObjectSchematic, A3144469 - 4366 - 4D77 - 870A - 9D3536723CDA, gbmpmodel, IElementRegenerationComponent)
            DBOBJECT_DATA_END
    public:
        virtual bool SetOwnerElement(IElement* pOwnerElement) override;
        virtual const IElement* GetOwnerElement() const override { return m_opOwnerElement; }
        virtual IElement* GetOwnerElement() override { return m_opOwnerElement; }
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }
       
    public:
        SectionViewSymbolNewRegenerationBehavior(IElement* pElement);

        virtual bool CanHaveRegenData() const override;

        virtual bool CanHaveCalculators() const override;

        virtual void GetCalculators(ICalculatorCollection* calculators) const override;

    private:
        IDocument* GetDocument() const;

    private:
        IElement* m_opOwnerElement;
        OwnerPtr<IElementRegenerationComponent> m_ElementRegenerationBehavior;
    };

    class SectionViewSymbolNewCopyStrategyComponent : public NdbObjectSchematic, public IElementCopyStrategyComponent
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewCopyStrategyComponent, gcmp::NdbObjectSchematic, 63C54A76 - 37D8 - 4F58 - B1FD - DC023773D0D3, gbmpmodel, IElementCopyStrategyComponent)
            DATA(OwnerPtr<IElementCopyStrategyComponent>, CopyStrategyComponent)
            DATA_TRANSIENT(IElement*, pOwnerElement)
        DBOBJECT_DATA_END
    public:
        virtual void Report(const gcmp::ICopyContext & copyContext, gcmp::ICopyStrategyReporter& reporter) const override;
    public:
        virtual bool SetOwnerElement(IElement* pOwnerElement) override;
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement; }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement; }
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }
    };

    class SectionViewSymbolNewCopyPasteComponent : public NdbObjectSchematic, public IElementCopyPasteComponent
    {
        DBOBJECT_DATA_BEGIN_AND_QUICK_CAST_FROM(gcmp, SectionViewSymbolNewCopyPasteComponent, gcmp::NdbObjectSchematic, 1639C408-07A8-4606-A528-72DC613D12AA, gbmpmodel, IElementCopyPasteComponent)
            DATA(OwnerPtr<IElementCopyPasteComponent>, CopyPasteComponent)
            DATA_TRANSIENT(IElement*, pOwnerElement)
        DBOBJECT_DATA_END
    public:
        SectionViewSymbolNewCopyPasteComponent(IElement* pElement);

        virtual OwnerPtr<IPasteHelper> GetPasteHelper() const override;

        virtual void UpdateAfterCopy(const ICopyContext& copyContext) override;

        virtual void UpdateForWeakParentCopied(const IDocument* pDocFrom, const IElement* pSource, const IElement* pCopy) const override;

        virtual bool ShouldBeCopiedTogether(const ICopyContext & copyContext) const override;

        virtual bool IsStrongParentsNeedCopied() const override;

        virtual bool CanBeCopied(std::wstring* pErrorMessage) const override;

    public:
        virtual IElement* GetOwnerElement() override { return m_pOwnerElement; }
        virtual const IElement* GetOwnerElement() const override { return m_pOwnerElement; }
        virtual bool SetOwnerElement(IElement* pOwnerElement) override;
    public: //实现NdbObject接口
        virtual NdbObject* GetTopOwnerObject() const override
        {
            return nullptr;
        }
    };
}
